package com.eunion.web.admin.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
//import org.apache.shiro.SecurityUtils;
//import org.apache.shiro.authc.AuthenticationException;
//import org.apache.shiro.authc.ExcessiveAttemptsException;
//import org.apache.shiro.authc.IncorrectCredentialsException;
//import org.apache.shiro.authc.LockedAccountException;
//import org.apache.shiro.authc.UnknownAccountException;
//import org.apache.shiro.authc.UsernamePasswordToken;
//import org.apache.shiro.crypto.hash.Md5Hash;
//import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.method.P;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.eunion.boot.security.SpringSecurityUtil;
import com.eunion.core.LogUtil;
import com.eunion.core.exception.ValidateException;
import com.eunion.web.admin.bo.AuthUserBo;
import com.eunion.web.admin.service.AdminUserService;
import com.eunion.web.common.vo.Web;
import com.eunion.web.common.vo.WebStatus;
import com.eunion.common.util.CommUtils;

@Controller
@RequestMapping(value = "/admin")
public class AdminController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private AdminUserService adminUserService;

    @ModelAttribute
    public void populateModel(Model model) {
        model.addAttribute("reqUrl",(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()).getRequestURI());
    }
    
    /**
     * 清理user session.
     */
    private void cleanSession() {
        try {
            SpringSecurityUtil.invalidateUser();
            // httpSession.invalidate();
        } catch (IllegalStateException e) {
            logger.warn("session already invalidated {}", e.toString());
        }
    }

    /**
     * 系统概览.
     */
    @RequestMapping(value = "/portal", method = RequestMethod.GET)
    public String portal(Model model) {
        return "admin/portal";
    }

    /**
     * 系统概览.
     */
    @PreAuthorize("isAuthenticated()")
    @RequestMapping(value = "/dashboard", method = RequestMethod.GET)
    public String dashboard(Model model) {
        return "admin/dashboard";
    }

    /**
     * 跳转到登录页面.
     */
    private String relogin(String message, HttpSession httpSession) {
        cleanSession();
        resetSession(httpSession);
        // redirectAttributes.addFlashAttribute("message", message);//F5 参数丢失，因为flash scope只支持redirect
        // redirectAttributes.addFlashAttribute(Web.STATUS, new WebStatus().setCodeError(message));
        httpSession.setAttribute("message", message);
        httpSession.setAttribute(Web.STATUS, new WebStatus().setCodeError(message));
        return "admin/login";
    }

    /**
     * 将session中的错误信息清空.
     */
    private void resetSession(HttpSession httpSession) {
        httpSession.removeAttribute("message");
        httpSession.removeAttribute(Web.STATUS);
    }

    /**
     * 跳转到登陆页面.
     */
    @RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
    public String main(HttpSession httpSession) {
        if (StringUtils.isEmpty(SpringSecurityUtil.getCurrentUserName())) {
            return relogin("会话失效,请重新登陆!", httpSession);
        }
        resetSession(httpSession);
        // return "admin/main";
        // 登录成功后，直接到权限页面
        return "redirect:/admin/adminauth";
    }

    /**
     * 跳转到登陆页面.
     */
    @RequestMapping(value = {"/main", "/index"}, method = RequestMethod.GET)
    public String index(Model model, HttpSession httpSession) {
        if (StringUtils.isEmpty(SpringSecurityUtil.getCurrentUserName())) {
            return relogin("会话失效,请重新登陆!", httpSession);
        }
        resetSession(httpSession);
        return "admin/loginok";
    }

    @RequestMapping(value = "/logout", method = {RequestMethod.GET, RequestMethod.POST})
    public String logout(Model model, RedirectAttributes redirectAttributes) {
        cleanSession();
        redirectAttributes.addFlashAttribute("message", "您已安全退出!");// F5 参数丢失，因为flash scope只支持redirect
        redirectAttributes.addFlashAttribute(Web.STATUS, new WebStatus().setCodeError("您已安全退出!"));
        return "redirect:/admin/login";
    }

    /**
     * 跳转到登陆页面.
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(Model model) {
        if (StringUtils.isNotEmpty(SpringSecurityUtil.getCurrentUserName())) {
            return "redirect:/admin/";
        }
        return "admin/login";
    }

    @RequestMapping(value = "/logtab", method = RequestMethod.GET)
    public String logtab(Model model) {
        return "usertab";
    }

    /**
     * 跳转到空白页面.
     */
    @RequestMapping(value = "/blank", method = RequestMethod.GET)
    public String help(Model model) {
        return "pages/_blank";
    }

    @RequestMapping(value = "/pwdpage", method = RequestMethod.GET)
    public String pwdpage(Model model) {
        return "pwd";
    }

    /**
     * 修改密码.
     */
    @PreAuthorize("#obj.name == authentication.principal.username or hasAuthority('admin')")
    @RequestMapping(value = "/pwds", method = {RequestMethod.POST})
    public String pwd(@P("obj") @Valid AuthUserBo obj, BindingResult result, Model model) {
        try {
            if (result.hasErrors()) {
                List<ObjectError> list = result.getAllErrors();
                for (ObjectError error : list) {
                    if (StringUtils.isNotEmpty(error.getDefaultMessage())) {// error.getObjectName());
                        // error.getArguments()[0]);
                        throw new ValidateException(error.getDefaultMessage());
                    }
                }
            }
            if (StringUtils.isEmpty(SpringSecurityUtil.getCurrentUserName())) {
                model.addAttribute(Web.STATUS, new WebStatus().setCodeError("修改密码失败,请求非法"));
            } else if (!obj.getPassword().equals(obj.getRePassword())) {
                model.addAttribute(Web.STATUS, new WebStatus().setCodeError("修改密码失败,2次新密码不同"));
            } else if (obj.getPassword().equals(obj.getOldPassword())) {
                model.addAttribute(Web.STATUS, new WebStatus().setCodeError("新旧密码相同，无需修改"));
            } else {
                int flag = adminUserService.updatePassword(CommUtils.getMd5(obj.getPassword()), SpringSecurityUtil.getCurrentUserName(), CommUtils.getMd5(obj.getOldPassword()));
                logger.debug("修改密码状态:{}", flag);
                if (flag > 0) {
                    model.addAttribute(Web.STATUS, new WebStatus().setCodeOK("修改密码成功"));
                } else {
                    model.addAttribute(Web.STATUS, new WebStatus().setCodeError("修改密码失败"));
                }
            }

        } catch (ValidateException ve) {
            model.addAttribute(Web.STATUS, new WebStatus().setCodeError(ve.getMsg()));
        } catch (Exception e) {
            LogUtil.get(this.getClass()).error("save obj error : {}", e);
            model.addAttribute(Web.STATUS, new WebStatus().setCodeError("修改密码异常"));
        }
        return "pwd";
    }

}
